package com.baichang.taoshunda.service.impl;

import com.alipay.api.AppPay;
import com.baichang.framework.excelption.ServiceException;
import com.baichang.framework.utils.KidUtils;
import com.baichang.taoshunda.dao.RedPacketDao;
import com.baichang.taoshunda.dao.RedPacketHistoryDao;
import com.baichang.taoshunda.dao.UserDao;
import com.baichang.taoshunda.entity.Bussiness;
import com.baichang.taoshunda.entity.RedPacket;
import com.baichang.taoshunda.entity.RedPacketHistory;
import com.baichang.taoshunda.entity.User;
import com.baichang.taoshunda.service.BusinessService;
import com.baichang.taoshunda.service.RedPacketService;
import com.baichang.taoshunda.service.UserService;
import com.weixin.pay.api.WeixinPay;
import com.weixin.pay.api.model.PayInfo;
import org.apache.commons.collections.map.HashedMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.*;


/**
 * Created by ${wushenglu} on 2018/4/26.
 */
@Service
public class RedPacketServiceImpl implements RedPacketService {
    @Autowired
    private RedPacketDao redPacketDao;
    @Autowired
    private RedPacketHistoryDao redPacketHistoryDao;
    @Autowired
    private BusinessService businessService;
    @Autowired
    private UserService userService;
    @Autowired
    private UserDao userDao;

    @Override
    public Map addRedPacket(Integer busId, Integer number, double money, String content, Integer payType, Integer cityId) {
        boolean flag = false;
        Map map = new HashMap();
        RedPacket redPacket = new RedPacket();
        redPacket.setAllMoney(BigDecimal.valueOf(money));
//        try {
//            redPacket.setContent(EmojiUtil.emojiConvert1(content));
//        } catch (UnsupportedEncodingException e) {
//            e.printStackTrace();
//        }
        redPacket.setContent(content);
        redPacket.setPayType(payType);
        redPacket.setAllNumber(number);
        redPacket.setNumber(number);
        redPacket.setCompanyId(busId);
        redPacket.setIsComplete(0);
        redPacket.setStatus(0);
        redPacket.setTimeLength(0);
        redPacket.setCreated(new Date());
        redPacket.setCityId(cityId);
        long redPacketId = redPacketDao.save(redPacket);
        List redPacketList = getRed(number, money, 0.01);
        //最佳红包位置
        int indexOfNumber = redPacketList.indexOf(Collections.max(redPacketList));
        for (int i = 0; i < redPacketList.size(); i++) {
            RedPacketHistory redPacketHistory = new RedPacketHistory();
            redPacketHistory.setCompanyId(busId);
            if (i == 0) {
                redPacketHistory.setIsFirst(1);
            } else {
                redPacketHistory.setIsFirst(0);
            }
            if (i == indexOfNumber) {
                redPacketHistory.setIsMax(1);
            } else {
                redPacketHistory.setIsMax(0);
            }
            redPacketHistory.setRedId((int) redPacketId);
            Object redPacketMoney = redPacketList.get(i);
            redPacketHistory.setUserMoney(BigDecimal.valueOf(Double.parseDouble(redPacketMoney.toString())));
            flag = redPacketHistoryDao.save(redPacketHistory) > 0;
        }
        if (flag) {
            String title = "商家服务费总付款：" + money + "元";
            String payOrderKid = "payOrder" + KidUtils.getKid();
            if (payType == 1) {
                //支付宝
                String aplipay = AppPay.createPay(title, payOrderKid, title, money);//这里传的是支付订单编号
                map.put("pay", aplipay);
            } else if (payType == 2) {
                int price = BigDecimal.valueOf(money).multiply(BigDecimal.valueOf(100)).intValue();
                WeixinPay weixinPay = new com.weixin.pay.api.AppPay();
                PayInfo payInfo = new PayInfo();
                payInfo.setBody(title);
                payInfo.setTradeNo(payOrderKid);
                payInfo.setSubject(title);
                payInfo.setPrice(price);
                payInfo.loadWxConfig("wx48217cb07b14d413");
                weixinPay.setPayInfo(payInfo);
                map = weixinPay.createPay();
//                map = CompanyWeixinUtils.getPayInfo(title, price, payOrderKid);
            }
        }
        map.put("redPacketId", redPacketId);
        return map;
    }

    @Override
    public boolean updateRedPacketStatus(Integer redPacketId) {

        return redPacketDao.updateRedPacketStatus(redPacketId);
    }

    /**
     * 查询所有的红包
     *
     * @param nowPage
     * @param pageSize
     * @param userId
     * @param cityId
     * @return
     */
    @Override
    public List<Map<String, Object>> findRedPacketList(Integer nowPage, Integer pageSize, Integer userId, Integer cityId) {
//        return EmojiUtil.returnEmojiList(redPacketDao.findRedPacketList(nowPage, pageSize, userId, cityId), "content", "content");
        return redPacketDao.findRedPacketList(nowPage, pageSize, userId, cityId);
    }

    /**
     * 用户抢红包
     *
     * @param userId
     * @param redPacketId
     * @param trendsUserId
     * @return
     */
    @Override
    public Map<String, Object> grabRedPacket(Integer userId, Integer redPacketId, String trendsUserId) throws ServiceException {
        RedPacket redPacket = redPacketDao.getEntityById(redPacketId);
        synchronized (redPacket) {
            //没有领取的红包金额信息
            RedPacketHistory redPacketHistory = redPacketHistoryDao.getNextRedPacket(redPacketId);
            if (redPacket == null) {
                throw new ServiceException("来晚一步该红包已抢完");
            }
            Bussiness bussiness = businessService.getBusinessById(redPacket.getCompanyId());
            Map<String, Object> map = new HashedMap();
            map.put("allNumber", redPacket.getAllNumber());
            map.put("allMoney", redPacket.getAllMoney());
            map.put("number", (redPacket.getAllNumber() - redPacket.getNumber()) + 1);
            map.put("userGetMoney", redPacketHistory.getUserMoney());
            map.put("bussName", bussiness.getBussName());
            map.put("companyHeadPic", bussiness.getHeadPic());
            map.put("content", redPacket.getContent());
//            try {
//                map.put("content", EmojiUtil.emojiRecovery2(redPacket.getContent()));
//            } catch (UnsupportedEncodingException e) {
//                e.printStackTrace();
//            }
            int isSaveRedHistory = 0;
            redPacketHistory.setUserId(userId);
            redPacketHistory.setUserTime(new Date());
            redPacketHistory.setTrendsUserId(trendsUserId);
            if (redPacket.getNumber() == 1) {
                //修改红包为已抢完和个数
                long intervalTime = System.currentTimeMillis() - redPacket.getCreated().getTime();
                int timeLength = (int) (intervalTime * 1f / (1000 * 60));
                if (timeLength <= 1) {
                    map.put("timeLength", 1);
                } else {
                    map.put("timeLength", timeLength);
                }
                isSaveRedHistory = redPacketHistoryDao.update(redPacketHistory);
                redPacketDao.updateRedPacketIsCompleteAndNumber(redPacketId, redPacket.getNumber() - 1, 1, timeLength);
            } else {
                isSaveRedHistory = redPacketHistoryDao.update(redPacketHistory);
                redPacketDao.updateRedPacketIsCompleteAndNumber(redPacketId, redPacket.getNumber() - 1, 0, 0);
                map.put("timeLength", 0);
            }
            if (isSaveRedHistory > 0) {
                User user = userService.getUserBeanById(userId);
                BigDecimal money = user.getRedPacket().add(redPacketHistory.getUserMoney());
                user.setRedPacket(money);
                userDao.update(user);
            }
            List<Map<String, Object>> redPacketListHistory = redPacketHistoryDao.findAllHistory(redPacketId);
            map.put("redPacketListHistory", redPacketListHistory);
            return map;

        }


    }

    @Override
    public List<Map<String, Object>> findHistoryByUserId(Integer userId, Integer nowPage, Integer pageSize) {

        return redPacketHistoryDao.findHistoryByUserId(userId, nowPage, pageSize);
    }

    /**
     * 查看用户红包个数、手气最佳个数、总计金额、当前金额
     *
     * @param userId
     * @return
     */
    @Override
    public Map<String, Object> getRedPacketByUserId(Integer userId) throws ServiceException {
        User user = userService.getUserBeanById(userId);
        Map<String, Object> map = redPacketHistoryDao.getRedPacketByUserId(userId);
        map.put("money", user.getRedPacket());
        map.put("userName", user.getNickName());
        map.put("userHeadPic", user.getHeadPic());
        map.put("userRedPacket", user.getRedPacket());
        return map;
    }

    @Override
    public Map<String, Object> getRedPacketById(Integer redPacketId, Integer userId) throws ServiceException {
        RedPacket redPacket = redPacketDao.getEntityById(redPacketId);
        Bussiness bussiness = businessService.getBusinessById(redPacket.getCompanyId());
        Map<String, Object> map = new HashedMap();
        map.put("allNumber", redPacket.getAllNumber());
        map.put("allMoney", redPacket.getAllMoney());
        map.put("number", redPacket.getAllNumber() - redPacket.getNumber());
        Map<String, Object> userGetMoney = redPacketHistoryDao.getUserGetMoneyByIdAndUserId(redPacketId, userId);
        map.put("userGetMoney", userGetMoney.get("userMoney"));
        map.put("bussName", bussiness.getBussName());
        map.put("companyId", bussiness.getId());
        map.put("content", redPacket.getContent());
        map.put("companyHeadPic", bussiness.getHeadPic());
        List<Map<String, Object>> redPacketListHistory = redPacketHistoryDao.findAllHistory(redPacketId);
        map.put("redPacketListHistory", redPacketListHistory);
        if (redPacket.getTimeLength() <= 1) {
            map.put("timeLength", 1);
        } else {
            map.put("timeLength", redPacket.getTimeLength());
        }
        return map;
    }

    @Override
    public List<Map<String, Object>> findRedPacketHistory(Integer companyId, Integer nowPage, Integer pageSize) {

        return redPacketDao.findRedPacketHistory(companyId, nowPage, pageSize);
    }

    public List getRed(int number, double total, double min) {
        //红包数
        //int number = 300;
        //红包总额
        // float total = 500;
        double money;
        //最小红包
        //double min = 0.48;
        double max;
        int i = 1;
        List math = new ArrayList();
        DecimalFormat df = new DecimalFormat("###.##");
        if (number > 1) {
            while (i < number) {
                //保证即使一个红包是最大的了,后面剩下的红包,每个红包也不会小于最小值
                max = total - min * (number - i);
                int k = (int) (number - i) / 2;
                //保证最后两个人拿的红包不超出剩余红包
                if (number - i <= 2) {
                    k = number - i;
                }
                //最大的红包限定的平均线上下
                max = max / k;
                //保证每个红包大于最小值,又不会大于最大值
                money = (int) (min * 100 + Math.random() * (max * 100 - min * 100 + 1));
                money = money / 100;
                //保留两位小数
                money = Double.parseDouble(df.format(money));
                total -= money;
                total = Double.parseDouble(df.format(total));
                math.add(money);
                i++;
                //最后一个人拿走剩下的红包
                if (i == number) {
                    math.add(total);
                }
            }
        } else {
            math.add(total);
        }
        //取数组中最大的一个值的索引
        return math;
    }

    public static void main(String[] args) {
        System.out.println(getRed1(3, 1, 0.01));
    }

    public static List getRed1(int number, double total, double min) {
        //红包数
        //int number = 300;
        //红包总额
        // float total = 500;
        double money;
        //最小红包
        //double min = 0.48;
        double max;
        int i = 1;
        List math = new ArrayList();
        DecimalFormat df = new DecimalFormat("###.##");
        if (number > 1) {
            while (i < number) {
                //保证即使一个红包是最大的了,后面剩下的红包,每个红包也不会小于最小值
                max = total - min * (number - i);
                int k = (int) (number - i) / 2;
                //保证最后两个人拿的红包不超出剩余红包
                if (number - i <= 2) {
                    k = number - i;
                }
                //最大的红包限定的平均线上下
                max = max / k;
                //保证每个红包大于最小值,又不会大于最大值
                money = (int) (min * 100 + Math.random() * (max * 100 - min * 100 + 1));
                money = money / 100;
                //保留两位小数
                money = Double.parseDouble(df.format(money));
                total -= money;
                total = Double.parseDouble(df.format(total));
                math.add(money);
                i++;
                //最后一个人拿走剩下的红包
                if (i == number) {
                    math.add(total);
                }
            }
        } else {
            math.add(total);
        }
        //取数组中最大的一个值的索引
        return math;
    }
}
